<!--

/*
* Copyright (C) 2005-2013 University of Sydney
*
* Licensed under the GNU License, Version 3.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.gnu.org/licenses/gpl-3.0.txt
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/

/**
* brief description of file
*
* @author      Stephen White   <stephen.white@sydney.edu.au>
* @copyright   (C) 2005-2013 University of Sydney
* @link        http://Sydney.edu.au/Heurist
* @version     3.1.0
* @license     http://www.gnu.org/licenses/gpl-3.0.txt GNU License 3.0
* @package     Heurist academic knowledge management system
* @subpackage  Search
*/

-->

<html>
 <head>
  <meta http-equiv="content-type" content="text/html; charset=utf-8">
  <link rel="stylesheet" href="../../common/css/global.css">
  <link rel="stylesheet" href="../../common/css/edit.css">
  <link rel="stylesheet" href="../../common/css/printview.css">
  <link rel="stylesheet" type="text/css" href="../../common/css/calendar.css" />
  <title>Add a value to each record</title>

  <style type="text/css">
	#record-count {
		font-weight: bold;
	}
  </style>
 </head>

 <body class="popup" width=600 height=400 onload="init();">
  <script type="text/javascript" src="../../external/yui/2.8.2r1/build/yahoo/yahoo-min.js"></script>
  <script type="text/javascript" src="../../external/yui/2.8.2r1/build/json/json-min.js"></script>
  <script src="../../common/js/utilsLoad.js"></script>
  <script type="text/javascript" src="../../external/jquery/jquery.js"></script>
  <script src="../../common/js/hintDiv.js"></script>
  <script src="../../common/js/calendarViewer.js"></script>
  <script src="../../common/js/calendar.js"></script>
  <script src="../../records/edit/editRecord.js"></script>
  <script src="../../records/edit/inputUrlInclude.js"></script>
  <script src="../../common/php/getMagicNumbers.php"></script>

  <script>

var recIDs, rtyID, dtyID, value, fileID, wkt;
var scopeSelect,fieldSelect,inputDiv,statusDiv;
var resultSetIDs, resultSetTypes, selectedResultSetIDs, allSelectedIDs, rtyIDs = [];


var hBase = window.location.protocol + "//" + window.location.host +
			(top && top.HEURIST && top.HEURIST.basePath? top.HEURIST.basePath : window.location.pathname.match(/^\/[^\/]+\//));
var database = (top && top.HEURIST && top.HEURIST.database? top.HEURIST.database.name : location.search.match(/db=([^&]+)/)[1]);

function init () {
  top.HEURIST.edit.calendarViewer = calendarViewer;
  
  if(top.HEURIST.search){
    resultSetIDs = top.HEURIST.search.results.infoByDepth[0].recIDs; //all records
    selectedResultSetIDs = top.HEURIST.search.getLevelSelectedRecIDs(0).get(); //selected in zero level
    allSelectedIDs = top.HEURIST.search.getSelectedRecIDs().get(); //slected from all levels
    resultSetTypes = top.HEURIST.search.results.infoByDepth[0].rectypes;
  }else{ // fake for H4
    resultSetIDs = top.HEURIST.search4.recids_all;
    selectedResultSetIDs = top.HEURIST.search4.recids_sel;
    allSelectedIDs = top.HEURIST.search4.recids_sel;
    resultSetTypes = top.HEURIST.search4.rectypes;
  }
  
  inputDiv = document.getElementById("inputDiv");
  statusDiv = document.getElementById("statusDiv");
  scopeSelect = document.getElementById("scope-select");
  fieldSelect = document.getElementById("field-select");// fill scope select and default to resultset
  fillScope();
//fill Field select  - formated with rectypename.filedname sorted
  fillFields();
//bind onchange to add/replace field entry input depending on type selected and asynch call to check change validity
  createInputElement();
}

function fillScope(){
//add result count option default
  var opt = new Option("Current results set N = " + resultSetIDs.length, "resultSet");
  scopeSelect.appendChild(opt);
//selected count option
  if ( selectedResultSetIDs.length > 0) {
    opt = new Option("Selected results set N = " + selectedResultSetIDs.length, "selectedResultSet");
    scopeSelect.appendChild(opt);
    if ( allSelectedIDs.length > selectedResultSetIDs.length) {
      opt = new Option("All selected N = " + allSelectedIDs.length, "allSelected");
      scopeSelect.appendChild(opt);
    }
  }
//find all types for result and add option for each with counts.
  if(top.HEURIST.util.isArray(resultSetTypes)){
      for (var rty in resultSetTypes){
        if(rty>=0){
            rty = resultSetTypes[rty];
            rtyIDs.push(rty);
            opt = new Option("All "+top.HEURIST.rectypes.pluralNames[rty]+" N = "+top.HEURIST.rectypes.usageCount[rty],rty);
            scopeSelect.appendChild(opt);
        }
      }
  }else{
      for (var rty in resultSetTypes){
        rtyIDs.push(rty);
        opt = new Option("All "+top.HEURIST.rectypes.pluralNames[rty]+" N = "+top.HEURIST.rectypes.usageCount[rty],rty);
        scopeSelect.appendChild(opt);
      }
  }
// add onchange handler to fill fieldSelect
  scopeSelect.onchange = fillFields;
}

function getRecType(recID){
     if(top.HEURIST.search){
        return top.HEURIST.search.results.recSet[recID].record[4];
     }else{ 
        var record = top.HAPI4.currentRecordset.getById(recID) ;
        return top.HAPI4.currentRecordset.fld(record, 'rec_RecTypeID');
     }
}

function fillFields(){
  var dtys = {}, dtyNames = [],dtyNameToID = {};
  var rtys = {};
  var i,j,recID,rty,rtyName,dty,dtyName,fieldName,opt;
  //remove all options
  while (fieldSelect.options.length){
    fieldSelect.removeChild(fieldSelect.options[0]);
  }
  //for selected scope find all types
  switch(scopeSelect.value){
    case "resultSet":
      rtyIDs = [];
      for(i in resultSetIDs){
        recID = resultSetIDs[i];
        rty = getRecType(recID);
        if (!rtys[rty]){
          rtys[rty] = 1;
          rtyIDs.push(rty);
        }
      }
      break;
    case "selectedResultSet":
      rtyIDs = [];
      for(i in selectedResultSetIDs){
        recID = selectedResultSetIDs[i];
        rty = getRecType(recID);
        if (!rtys[rty]){
          rtys[rty] = 1;
          rtyIDs.push(rty);
        }
      }
      break;
    case "allSelected":
      rtyIDs = [];
      for(i in allSelectedIDs){
        recID = allSelectedIDs[i];
        rty = getRecType(recID);
        if (!rtys[rty]){
          rtys[rty] = 1;
          rtyIDs.push(rty);
        }
      }
      break;
    default:
      rtyIDs = [scopeSelect.value];
  }
//for all rectypes find all fields as Detail names sorted
  for (i in rtyIDs) {
    rty = rtyIDs[i];
    rtyName = top.HEURIST.rectypes.names[rty];
    for (dty in top.HEURIST.rectypes.typedefs[rty].dtFields) {
      if(top.HEURIST.detailTypes.typedefs[dty].commonFields[top.HEURIST.detailTypes.typedefs.fieldNamesToIndex['dty_Type']] in {"selector":1,"relmarker":1}){
        continue;
      }
      dtyName = top.HEURIST.detailTypes.names[dty];
      if (!dtys[dtyName]){
        dtys[dtyName] = [];
        dtyNameToID[dtyName] = dty;
        dtyNames.push(dtyName);
      }
      fieldName = rtyName + "." + top.HEURIST.rectypes.typedefs[rty].dtFields[dty][0];
      dtys[dtyName].push(fieldName);
    }
  }
  if (dtyNames.length >0) {
    dtyNames.sort();
  //add option for DetailType enabled followed by all Rectype.Fieldname options disabled
    for (i in dtyNames) {
      dtyName = dtyNames[i];
      opt = new Option(dtyName, dtyNameToID[dtyName]);
      fieldSelect.appendChild(opt);
      //sort RectypeName.FieldName
      dtys[dtyName].sort();
      for (j in dtys[dtyName]){
        fieldName = dtys[dtyName][j];
        opt = new Option(".  ."+fieldName, "");
        opt.innerHTML = "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"+fieldName;
        opt.disabled = "disabled";
        fieldSelect.appendChild(opt);
      }
    }
  }else{
    opt = new Option("no suitable fields", "");
    fieldSelect.appendChild(opt);
  }
  fieldSelect.onchange = createInputElement;
  createInputElement();
}

function createInputElement(){
  inputDiv.innerHTML = "";
  top.HEURIST.edit.allInputs = [];
  top.HEURIST.edit.createSeparator("Value to add",inputDiv);
  top.HEURIST.edit.createInput("addValue",fieldSelect.value,null,[],inputDiv,null);
}

function cbSave(results){
  var html = "",i;
  if(top.HEURIST.util.isnull(results)){
    alert("Failed to return results from replace detail (value) action!");
    return
  }
  if (results.none){
    html += "<p>"+results.none+"</p>";
  }else if (results.problem){
    html += "<p style=\"color: red;\">"+results.problem+"</p>";
  }
  if (results.count && (results.count.rtyRecs || results.count.passed)){
    if (results.count.processed > 0 && top.HEURIST.search) {
      html += '<br><input type=\"button\" value=\"Requery\"'+
              ' title=\"Click to force re-query in order to show updated results\"'+
              ' onclick="{top.HEURIST.search.executeQuery(top.HEURIST.currentQuery_main);}">';
    }
    html += "<div style=\"color: #DC8501; padding-top:5px\"> Results : </div><ul>";
    if (results.count.passed > 0) {
      html += "<li> Records passed to process .............. "+results.count.passed+"</li>";
    }
    if (results.count.rtyRecs > 0) {
      html += "<li> Records of correct type .......... "+results.count.rtyRecs+"</li>";
    }
    if (results.count.noAccess > 0) {
      html += "<li> Inaccessible records (restricted access) .... "+results.count.noAccess+"</li>";
    }
    if (results.count.processed > 0) {
      html += "<li><strong> Records processed ....... "+results.count.processed+"</strong>"+
              "...<a target=_new title=\" View added results -tagged "+ results.added.tagResults +"\""+
              " href=\""+encodeURI(hBase+ "search/search.html?db="+database+"&q="+results.added.queryString)+"\">view processed records</a></li>";
    }
    if (results.count.notDefined > 0) {
      html += "<li> Records with undefined field ... "+results.count.notDefined+
              "...<a target=_new title=\" View not defined results -tagged "+ results.notDefined.tagResults +"\""+
              " href=\""+encodeURI(hBase+ "search/search.html?db="+database+"&q="+results.notDefined.queryString)+"\">view undefiend field records</a></li>";
    }
    if (results.count.limitted > 0) {
      html += "<li> Records exceeding field repeat limit ..... "+results.count.limitted+
              "...<a target=_new title=\" View max limit results -tagged "+ results.limitted.tagResults +"\""+
              " href=\""+encodeURI(hBase+ "search/search.html?db="+database+"&q="+results.limitted.queryString)+"\">view repeat limit exceeded records</a></li>";
    }
    if (results.count.error > 0) {
      html += "<li> Records with insert errors .... "+results.count.error+
              "...<a target=_new title=\" View error results -tagged "+ results.errors.tagResults +"\""+
              " href=\""+encodeURI(hBase+ "search/search.html?db="+database+"&q="+ results.errors.queryString)+"\">view insert error records</a></li>";
      if (results.errors.byRecID) {
        html += "<ul>";
        for ( i in results.errors.byRecID) {
          html += "<li>" + results.errors.byRecID[i] + "</li>";
        }
        html += "</ul>";
      }
    }
    html += "</ul>";
  }
  statusDiv.innerHTML = html;
}

function save() {
  var _data = {};
//need to extract the value for the input and return all appropriate values
  if (scopeSelect.value == "allSelected") {
    recIDs = allSelectedIDs;
  }else if (scopeSelect.value == "resultSet") {
    recIDs = resultSetIDs;
  }else if (scopeSelect.value == "selectedResultSet") {
    recIDs = selectedResultSetIDs;
  }else {
    rtyID = scopeSelect.value;
  }
  var allInputs = top.HEURIST.edit.allInputs;
  var addInput, i;
  for (i=0; i<allInputs.length; i++){
    if ( allInputs[i].recID == "addValue") {
      addInput = allInputs[i].inputs[0];
    };
  }
  if (!addInput) {
    alert("no valid add input element found, unable to proceed with add");
    return;
  }
  value = (addInput.value || addInput.input.value ||
            (addInput.hiddenElt ? addInput.hiddenElt.value:false) ||
            (addInput.textElt ? addInput.textElt.strTemporal:false));
  if (!value){
    alert("No value found, please enter a field value to add");
    return;
  }
  match = value.match(/^(p(?= point)|r(?= polygon)|[cl](?= linestring)|pl(?= polygon)) ((?:point|polygon|linestring)\(?\([-0-9.+, ]+?\)\)?)$/i);
  if (match && match[2]) {
    value = match[1];
    wkt = match[2];
  }
  match = value.match(/^\{"id":(\d+).*}$/);
  if (match && match[1]) {
   fileID = match[1];
   value = null;
  }
  _data.recIDs = recIDs;
  _data.dtyID =  fieldSelect.value;
  _data.dtyName = fieldSelect.options[fieldSelect.selectedIndex].label;
  if (rtyID) _data.rtyID = rtyID;
  if (value) _data.val = value;
  if (fileID) _data.ulfID = fileID;
  if (wkt) _data.geo = wkt;
  statusDiv.innerHTML = "<div id=\"loading\"/>";
  if(top.HEURIST.search){
    top.HEURIST.search.executeAction( "add_detail", _data, cbSave );
  }else{
    top.HEURIST.search4.executeAction( "add_detail", _data, cbSave );
  }
  
//alert("the value is "+ value + "wkt = " + wkt);

}


  </script>
   <p>This function adds a new value for a specified field to each record. Existing values are unaffected. New values cannot be added to records where this will cause the maximum count for that field to be exceeded (eg. adding a value to a single value field where a value is already recorded).</p>

   <div id="uiControls">
     <div style="padding-top: 5px;"><label for="scope-select">Add value to: </label><select id="scope-select"></select></div>
     <div style="padding-top: 5px; padding-left: 5px;"><label for="field-select">Select Field: </label><select id="field-select"></select></div>
     <div id="inputDiv"><label for="value">Value: </label><input  type="text" id="value"/></div>
   </div>
   <input type="button" value="Go" onclick="save();">
   <input type="button" value="Close" onclick="window.close();">

   <div id="statusDiv"></div>

 </body>
</html>
